package com.zqxq.common.utils;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;

/**
 * 提供精确的加减乘除运算
 */
public class BigDecimalUtils {
	
	/**
	 * 默认保留位：2
	 */
	private static int 	DEFAULT_SCALE = 2;
	
	/**
	 * 默认四舍五入规则为：向上舍入
	 */
	private static int DEFAULT_ROUND = BigDecimal.ROUND_HALF_UP;


	 public static Double getScale(Double d,Integer scale){
		if (null == scale){
			scale=DEFAULT_SCALE;
		}
		if (null==d) return 0.0;
		 String t=String.valueOf(d);
		 if (t.indexOf(".")==-1){	//没小数点

			return d;
		}
		BigDecimal big=getBigDecimal(d);
		d=big.setScale(scale,BigDecimal.ROUND_HALF_UP).doubleValue();
		return d;
	 }
	public static Object getScaleObj(Double d,Integer scale){
		d=getScale(d,scale);
		String t=String.valueOf(d);
		if (Integer.parseInt(t.substring(t.indexOf(".")+1))==0){
			return d.intValue();
		}
		return d;
	}

	/**
	 * 
	 * 加法运算
	 *
	 * @param v1	加数
	 * @param v2	被加数
	 * @return
	 */
	public static String add(String v1,String v2){    
        BigDecimal b1 = new BigDecimal(v1);    
        BigDecimal b2 = new BigDecimal(v2);    
        return b1.add(b2).toString();
    }

	public static Double add_double(Double v1,Double v2){

		return add(v1,v2).doubleValue();
	}

	public static BigDecimal add(Double v1,Double v2){
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.add(b2);
	}
	/**
	 * 减法
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static Double sub_double(Double v1,Double v2){

		return sub(v1,v2).doubleValue();
	}

	public static BigDecimal sub(Double v1,Double v2){
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.subtract(b2);
	}

	public static BigDecimal sub(BigDecimal v1,BigDecimal v2){

		return v1.subtract(v2);
	}
	public static Double subDouble(BigDecimal v1,BigDecimal v2){

		return v1.subtract(v2).doubleValue();
	}
	/**
	 * 乘法
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static BigDecimal multiply(BigDecimal v1,BigDecimal v2){

		return v1.multiply(v2);
	}

	public static BigDecimal multiply(Double v1,Double v2){
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.multiply(b2);
	}
	public static BigDecimal multiply(Integer v1,Integer v2){
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.multiply(b2);
	}
	public static Double multiplyDouble(BigDecimal v1,BigDecimal v2){

		return v1.multiply(v2).doubleValue();
	}
	/**
	 * 除法运算<br>
	 * 当发生除不尽的情况时，由scale参数指定精度，以后的数字四舍五入。
	 *
	 * @param v1 除数
	 * @param v2 被除数
	 * @param scale 精确精度
	 * @return
	 */
	public static String div(String v1, String v2, int scale, int round) {
		if (scale < 0) {
			throw new IllegalArgumentException(
					"The scale must be a positive integer or zero");
		}

		if (StringUtils.isEmpty(scale)) {
			scale = DEFAULT_SCALE;
		}

		if (StringUtils.isEmpty(round)) {
			round = DEFAULT_ROUND;
		}

		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP).toString();
	}
	//乘法
	public static BigDecimal divpercent(Integer v1, Integer v2) {

		return divpercent(v1,v2,DEFAULT_SCALE);
	}
	public static BigDecimal divpercent(Integer v1, Integer v2,int scale) {

		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		Double temp = b1.divide(b2,4, BigDecimal.ROUND_HALF_UP).doubleValue();
		if (StringUtils.isEmpty(scale)) {
			scale = DEFAULT_SCALE;
		}
		return multiply(temp,100.0).setScale(scale,BigDecimal.ROUND_HALF_UP);
	}

	public static BigDecimal div(Integer v1, Integer v2) {

		return div(v1,v2,DEFAULT_SCALE);
	}
	public static BigDecimal div(Integer v1, Integer v2, int scale) {
		if (scale < 0) {
			throw new IllegalArgumentException(
					"The scale must be a positive integer or zero");
		}

		if (StringUtils.isEmpty(scale)) {
			scale = DEFAULT_SCALE;
		}
		BigDecimal b1 = new BigDecimal(v1);
		BigDecimal b2 = new BigDecimal(v2);
		return b1.divide(b2, scale, BigDecimal.ROUND_HALF_UP);
	}
	/**
	 * 比较两个数<br>
	 * v1 > v2 return 1<br>
	 * v1 = v2 return 0<br>
	 * v1 < v2 return -1
	 *
	 * @param v1 比较数
	 * @param v2 被比较数
	 * @return
	 */
	public static int compareTo(String v1,String v2){    
        BigDecimal b1 = new BigDecimal(v1);    
        BigDecimal b2 = new BigDecimal(v2);    
        return b1.compareTo(b2);    
    }   
	
	/**
	 * 返回较小数
	 *
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static String returnMin(String v1,String v2){    
        BigDecimal b1 = new BigDecimal(v1);    
        BigDecimal b2 = new BigDecimal(v2);    
        return b1.min(b2).toString();    
    }   
	
	/**
	 * 返回较大数
	 *
	 * @param v1
	 * @param v2
	 * @return
	 */
	public static String returnMax(String v1,String v2){    
        BigDecimal b1 = new BigDecimal(v1);    
        BigDecimal b2 = new BigDecimal(v2);    
        return b1.max(b2).toString();    
    }   
	
	/**
	 * 处理BigDecimal数据，保留scale位小数
	 *
	 * @param value
	 * @param scale
	 * @return
	 */
	public static BigDecimal getValue(BigDecimal value,int scale){
		if(!StringUtils.isEmpty(value)){
			return value.setScale(scale, BigDecimal.ROUND_HALF_UP);
		}
		return value;
	}
	
	/**
	 * 将object转换为Bigdecimal
	 *
	 * @param value 待转换的数值
	 * @return
	 */
	public static BigDecimal getBigDecimal(Object value){

		BigDecimal resultValue = new BigDecimal(0);
		if (null==value){
			return resultValue;
		}
		if(value instanceof String){
			if ("".equals(value)){
				return resultValue;
			}
			resultValue =  new BigDecimal((String)value);
		}
		else if(value instanceof Integer){
			resultValue =  new BigDecimal((Integer)value);
		}
		else if(value instanceof Long){
			resultValue =  new BigDecimal((Long)value);
		}
		else if(value instanceof Double){
			resultValue =  new BigDecimal((Double)value);
		}
		else{
			resultValue = (BigDecimal) value;
		}
		
		return resultValue;
	}
	
	
	/**
	 * 将object转换为Bigdecimal,若object为空，则返回resultValue
	 *
	 * @param value
	 * @return
	 */
	public static BigDecimal getBigDecimal(Object value,BigDecimal resultValue){
		if(StringUtils.isEmpty(value)){
			return resultValue;
		}
		
		resultValue = getBigDecimal(resultValue);
		
		return resultValue;
	}
	
	/**
	 * 将BigDecimal 转换成Long
	 *
	 * @param value
	 * @return
	 */
	public static Long bigDecimalToLong(BigDecimal value){
		if(value != null){
			return new Long(value.longValue());
		}
		return null;
	}
	
	/**
	 * 将BigDecimal 转换成integer
	 *
	 * @param value
	 * @return
	 */
	public static Integer bigDecimalToInteger(BigDecimal value){
		if(value != null){
			return new Integer(value.intValue());
		}
		return null;
	}

	/**
	 * 将double转换成 Decimal
	 * @param value
	 * @return
	 */
	public static BigDecimal doubleToDecimal(Double value){
		if(value == null){
			value=0.0;
		}
		return new BigDecimal(value);
	}





	/**
	 * 当浮点型数据位数超过10位之后，数据变成科学计数法显示。用此方法可以使其正常显示。
	 * @param value
	 * @return Sting
	 */
	public static String formatDoubleNumber(double value) {
		if(value != 0.00){
			java.text.DecimalFormat df = new java.text.DecimalFormat("########.00");
			return df.format(value);
		}else{
			return "0.00";
		}
	}
	public  static String formatDoubleNumber(Double value) {
		if(value != null){
			if(value.doubleValue() != 0.00){
				java.text.DecimalFormat df = new java.text.DecimalFormat("########.00");
				return df.format(value.doubleValue());
			}else{
				return "0.00";
			}
		}
		return "";
	}

	public static BigDecimal toBigDecimal(Double value,Integer scale,Integer round){
		if (null==scale){
			scale=DEFAULT_SCALE;
		}
		if (null==round){
			scale=DEFAULT_ROUND;
		}
		BigDecimal bigDecimal = new BigDecimal(value).setScale(scale,round);
		return bigDecimal;
	}
	public static BigDecimal toBigDecimal(Double value,Integer scale){
		if (null==scale){
			scale=DEFAULT_SCALE;
		}
		BigDecimal bigDecimal = new BigDecimal(value).setScale(scale,DEFAULT_ROUND);
		return bigDecimal;
	}
	public static BigDecimal toBigDecimal(Double value){

		return toBigDecimal(value,DEFAULT_SCALE,DEFAULT_ROUND);
	}
	public static String toBigDecimalStr(Double value){

		return toBigDecimal(value,DEFAULT_SCALE,DEFAULT_ROUND).toString();
	}
	public static BigDecimal toBigDecimal(Integer value){
		Double temp = new Double(value);
		return toBigDecimal(temp,DEFAULT_SCALE,DEFAULT_ROUND);
	}

	public static String toBigDecimalStr(Integer value){

		return toBigDecimal(value).toString();
	}
	public static void main(String[] args) {
		Double profit=2068000000000000000000.074998;

		System.out.println(new BigDecimal(profit).toString());
	}

}
